/*****************************************************************************
 *  This file is part of the OpenDomo project.
 *  Copyright(C) 2011 OpenDomo Services SL
 *  
 *  Daniel Lerch Hostalot <dlerch@opendomo.com>
 *
 *  This program is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
 *****************************************************************************/



#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/resource.h>
#include <sys/types.h>
#include <sys/stat.h>

#include "daemonize.h"


// {{{ daemonize()
void daemonize(const char* cmd)
{
   int i, fd0, fd1, fd2;
   pid_t pid;
   struct rlimit r1;
   struct sigaction sa;

   // Clear file creation mask
   umask(0);

   // Get maximum number of file descriptors
   if(getrlimit(RLIMIT_NOFILE, &r1)<0)
   {
      perror("daemonize(): getrlimit() \n");
      exit(0);
   }

   // Become a session leader to lose controllling TTY
   if((pid = fork())<0)
   {
      perror("daemonize(): fork() \n");
      exit(0);
   }
   else if(pid!=0)
   {
      exit(0);
   }
   setsid();

   // Ensure future opens won't allocate controllling TTYs
   sa.sa_handler = SIG_IGN;
   sigemptyset(&sa.sa_mask);
   sa.sa_flags = 0;

   if(sigaction(SIGHUP, &sa, NULL)<0)
   {
      perror("daemonize(): sigaction() can't ignore SIGHUP \n");
      exit(0);
   }

   if((pid = fork())<0)
   {
      perror("daemonize(): fork() \n");
      exit(0);
   }
   else if(pid!=0)
   {
      exit(0);
   }

   // Change the current working directory to '/' so we won't prevent
   // file systems from being unmounted
   if(chdir("/")<0)
   {
      perror("daemonize(): chdir() \n");
      exit(0);
   }

   // Close all open file descriptors
   if(r1.rlim_max == RLIM_INFINITY)
      r1.rlim_max = 1024;

   for(i=0; i<r1.rlim_max; i++)
      close(i);

   // Attach file descriptors 0, 1 and 2 to /dev/null
   fd0 = open("/dev/null", O_RDWR);
   fd1 = dup(0);
   fd2 = dup(0);
}
// }}}



